package com.example.chessbattleplatform.web.Sys_User.Service;


import cn.hutool.crypto.digest.DigestUtil;
import com.example.chessbattleplatform.Pojo.Exception.BusinessException;
import com.example.chessbattleplatform.Pojo.Exception.StatusCode;
import com.example.chessbattleplatform.Pojo.Result.WebResult;
import com.example.chessbattleplatform.utils.GetLocalDateTimeUtils;
import com.example.chessbattleplatform.utils.JwtUtils;
import com.example.chessbattleplatform.utils.UserLoginHistoryIsCachedUtils;
import com.example.chessbattleplatform.web.Sys_User.CopyUtils.CopyUser;
import com.example.chessbattleplatform.web.Sys_User.Pojo.Vo.LoginVo;
import com.example.chessbattleplatform.web.Sys_User.Pojo.Vo.RegisterVo;
import com.example.chessbattleplatform.web.Sys_User.Pojo.Vo.UpdateVo;
import com.example.chessbattleplatform.web.Sys_User.Pojo.dto.LoginEmailRequest;
import com.example.chessbattleplatform.web.Sys_User.Pojo.dto.LoginRequest;
import com.example.chessbattleplatform.web.Sys_User.Pojo.dto.RegisterRequest;
import com.example.chessbattleplatform.web.Sys_User.Pojo.mapper.User;
import com.example.chessbattleplatform.web.Sys_User.Service.impl.UserServiceInterface;
import com.example.chessbattleplatform.web.Sys_User.dataService.impl.UserDataServiceInterface;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.Map;

@Service
@RequiredArgsConstructor
@Slf4j
public class UserService implements UserServiceInterface {

    //
    private final UserDataServiceInterface userDataServiceinterface;
    //复制
    private final CopyUser copyUser;


    private final JwtUtils jwtUtils;
    // 缓存
    private final UserLoginHistoryIsCachedUtils userLoginHistoryIsCachedUtils;

    // 注册用户
    @Override
    public RegisterVo registerUser(RegisterRequest registerRequest) {
        //处理用户密码,防止防暴力破解并增强安全性
        registerRequest.setPassword(DigestUtil.md5Hex(registerRequest.getPassword()));
        //RegisterRequest -转-> User
        User addUser = copyUser.copyUser(registerRequest);
        // 设置默认头像为
        addUser.setAvatar("default-avatar");

        // 数据库 添加用户数据
        User userVo = userDataServiceinterface.addUser(addUser);

        return copyUser.copyRegisterVo(userVo);
    }


    private LoginVo getLoginVo(User login) {
        //再次对密码 进行MD5加密，防止防暴力破解并增强安全性
        String PasswordMD5 = DigestUtil.md5Hex(login.getPassword());

        Map<String, Object> u_key = Map.of("uid", login.getId(), "pwd", PasswordMD5);
        String jwt = jwtUtils.createJwt(u_key);

        //将用户数据放入缓存
        userLoginHistoryIsCachedUtils.userLoginHistoryIsCached(login.getId(),  jwt);

        //登录成功后将token返回给前端
        LoginVo loginVo = copyUser.loginVo(login);
        loginVo.setJwtKey(jwt);
        return loginVo;
    }

    // 登录用户
    @Override
    public LoginVo loginUser(LoginRequest user) {
        String PasswordMD5 = DigestUtil.md5Hex(user.getPassword());
        User login = userDataServiceinterface.login(user.getName(), PasswordMD5);

        return getLoginVo(login);
    }

    // 登录用户 通过邮箱
    @Override
    public LoginVo loginUserEmail(LoginEmailRequest user) {
        String PasswordMD5 = DigestUtil.md5Hex(user.getPassword());
        User login = userDataServiceinterface.loginEmail(user.getEmail(), PasswordMD5);

        return getLoginVo(login);
    }

    //修改密码
    @Override
    @CacheEvict(value = "UserService", key = "#ID")
    public UpdateVo modifyPassword(Long ID, String oldPassword, String newPassword) {
        // 判断旧密码和新密码是否相同
        if (oldPassword.equals(newPassword)) {
            throw new BusinessException(StatusCode.BAD_REQUEST, "新密码不能与旧密码相同");
        }
        //判断旧密码是否正确
        String PasswordMD5 = DigestUtil.md5Hex(oldPassword);
        if (!userDataServiceinterface.isUserPasswordFind(ID, PasswordMD5)) {
            throw new BusinessException(StatusCode.BAD_REQUEST, "旧密码错误");
        }
        // 封装新密码
        User build = User.builder().id(ID).password(DigestUtil.md5Hex(newPassword)).build();

        //修改密码
        User user = userDataServiceinterface.updateUser(build);
        log.info("修改密码 测试 {}", user);

        return UpdateVo.builder().id(ID).updatedDate(GetLocalDateTimeUtils.GetLocalDateTimeToStrings()).build();
    }

    // 修改邮箱
    @Override
    @CacheEvict(value = "UserService", key = "#ID")
    public UpdateVo modifyEmail(Long ID, String oldEmail, String newEmail) {
        // 判断旧邮箱和新邮箱是否相同
        if (oldEmail.equals(newEmail)) {
            throw new BusinessException(StatusCode.BAD_REQUEST, "新邮箱不能与旧邮箱相同");
        }
        // 判断新邮箱是否已存在
        if (userDataServiceinterface.isUserEmailFind(newEmail)) {
            throw new BusinessException(StatusCode.BAD_REQUEST, "邮箱已存在,请重新输入!");
        }
        // 封装新邮箱
        User build = User.builder().id(ID).email(newEmail).build();
        // 修改邮箱
        userDataServiceinterface.updateUser(build);

        return UpdateVo.builder().id(ID).updatedDate(GetLocalDateTimeUtils.GetLocalDateTimeToStrings()).build();
    }

    // 修改用户名
    @Override
    @CacheEvict(value = "UserService", key = "#ID")
    public UpdateVo modifyUserName(Long ID, String oldUserName, String newUserName) {
        // 判断旧用户名和新用户名是否相同
        if (oldUserName.equals(newUserName)) {
            throw new BusinessException(StatusCode.BAD_REQUEST, "新用户名不能与旧用户名相同");
        }

        // 判断新用户名是否已存在
        if (userDataServiceinterface.isUsernameFind(newUserName)) {
            throw new BusinessException(StatusCode.BAD_REQUEST, "用户名已存在,请重新输入!");
        }

        // 封装新用户名
        User build = User.builder().id(ID).userName(newUserName).build();
        // 修改用户名
        userDataServiceinterface.updateUser(build);
        return UpdateVo.builder().id(ID).updatedDate(GetLocalDateTimeUtils.GetLocalDateTimeToStrings()).build();

    }

    // 修改头像
    @Override
    @CacheEvict(value = "UserService", key = "#ID")
    public UpdateVo modifyUserAvatar(Long ID, String newAvatar) {
        // 封装新头像
        User build = User.builder().id(ID).avatar(newAvatar).build();
        // 修改头像
        userDataServiceinterface.updateUser(build);
        return UpdateVo.builder().id(ID).updatedDate(GetLocalDateTimeUtils.GetLocalDateTimeToStrings()).build();
    }

    // 修改简介
    @Override
    @CacheEvict(value = "UserService", key = "#ID")
    public UpdateVo modifyUserIntroduction(Long ID, String introduction) {
        // 封装新简介
        User build = User.builder().id(ID).introduction(introduction).build();
        // 修改简介
       userDataServiceinterface.updateUser(build);
        return UpdateVo.builder().id(ID).updatedDate(GetLocalDateTimeUtils.GetLocalDateTimeToStrings()).build();

    }

    // 根据 jwt 查询用户
    @Override
    @Cacheable(value = "UserService", key = "#uid")
    public LoginVo getUserInfo(Long uid, String ParsePassword) {

        User user = userDataServiceinterface.IdGetUserInfo(uid);
        //处理用户修改密码后状态
        // 因为jwt加密了二次，所以在次加密
        String PasswordMD5 = DigestUtil.md5Hex(user.getPassword());

        // 验证
        if (!ParsePassword.equals(PasswordMD5)) {
            throw new BusinessException(StatusCode.UNAUTHORIZED, "验证失效请重新登录");
        }

        return copyUser.loginVo(user);
    }

    @Override
    @CacheEvict(value = "UserService", key = "#id")
    public WebResult<?> deleteUser(Long id) {
        userDataServiceinterface.deleteUser(id);
        //注销用户
        return WebResult.success("注销成功");

    }

}
